////////////////////////////////////////////////////////////////////////////////
// Filename: L_spriterenderer.cpp
////////////////////////////////////////////////////////////////////////////////
#include "L_spriterenderer.h"

L_SpriteRenderer::L_SpriteRenderer()
{
	Device = 0;
	DeviceContext = 0;
	VertexBuffer = 0;
}

L_SpriteRenderer::~L_SpriteRenderer()
{

}

bool L_SpriteRenderer::Init(ID3D11Device* tDevice, ID3D11DeviceContext* tDeviceContext, L_DX11ResourceManager* tResourceManager)
{
	Device = tDevice;
	DeviceContext = tDeviceContext;
	ResourceManager = tResourceManager;

	if(VertexBuffer == 0)
	{
		char* temp = new char[1000*sizeof(SpriteVertex)];
		for(int i=0;i<1000*sizeof(SpriteVertex);i++)
		{
			temp[i] = 0;
		}

		VertexBuffer = new L_DX11VertexBuffer;
		VertexBuffer->Init(Device, temp, 1000*sizeof(SpriteVertex), false);
	}

	return true;
}

void L_SpriteRenderer::BeginDraw()
{

}

void L_SpriteRenderer::EndDraw()
{

}

void L_SpriteRenderer::DrawSprite(L_Sprite Sprite)
{
	static ID3D11ShaderResourceView* tempTexture;
	tempTexture = ResourceManager->GetTexture(Sprite.GetTextureFilename());
	DeviceContext->PSSetShaderResources( 0, 1, &tempTexture );

	static SpriteVertex* temp = new SpriteVertex[6];
	static float uvWidth;
	uvWidth = Sprite.GetUV2().x - Sprite.GetUV1().x;

	temp[0].pos = float3((float)Sprite.GetPosX()-400.0f, (float)-Sprite.GetPosY()+300.0f, 0.0f);
	temp[0].texCoord = Sprite.GetUV1();

	temp[1].pos = float3((float)(Sprite.GetPosX()+Sprite.GetWidth())-400.0f, (float)-Sprite.GetPosY()+300.0f, 0.0f);
	temp[1].texCoord = Sprite.GetUV1();
	temp[1].texCoord.x += uvWidth;

	temp[2].pos = float3((float)(Sprite.GetPosX()+Sprite.GetWidth())-400.0f, (float)(-Sprite.GetPosY()-Sprite.GetHeight())+300.0f, 0.0f);
	temp[2].texCoord = Sprite.GetUV2();

	temp[3].pos = float3((float)Sprite.GetPosX()-400.0f, (float)-Sprite.GetPosY()+300.0f, 0.0f);
	temp[3].texCoord = Sprite.GetUV1();

	temp[4].pos = float3((float)(Sprite.GetPosX()+Sprite.GetWidth())-400.0f, (float)(-Sprite.GetPosY()-Sprite.GetHeight())+300.0f, 0.0f);
	temp[4].texCoord = Sprite.GetUV2();

	temp[5].pos = float3((float)Sprite.GetPosX()-400.0f, (float)(-Sprite.GetPosY()-Sprite.GetHeight())+300.0f, 0.0f);
	temp[5].texCoord = Sprite.GetUV2();
	temp[5].texCoord.x -= uvWidth;

	VertexBuffer->Update(DeviceContext, temp, 6*sizeof(SpriteVertex),0);

	ID3D11Buffer* tVB = VertexBuffer->GetBuffer();
	unsigned int Stride = sizeof(SpriteVertex);
	unsigned int Offset = 0;
	unsigned int NumPrimitives = static_cast<unsigned int>(VertexBuffer->GetSize()/Stride);
	DeviceContext->IASetVertexBuffers( 0, 1, &tVB, &Stride, &Offset );

	DeviceContext->Draw( 6, 0 );
}

void L_SpriteRenderer::DrawSprites(L_Sprite* Sprites, unsigned int NumSprites)
{
	
	static int CurrentSprite, CurrentLenght;
	static string CurrentTextureName;
	static float uvWidth;

	CurrentSprite = 0;
	CurrentLenght = 0;
	CurrentTextureName = Sprites[0].GetTextureFilename();

	for(unsigned int i=0; i<NumSprites;i++)
	{
		if(Sprites[i].GetTextureFilename() == CurrentTextureName)
		{
			CurrentLenght++;
		}
		else
		{
			DrawSpriteList( Sprites, CurrentLenght, CurrentSprite);
			CurrentLenght = 1;
			CurrentSprite = i;
			CurrentTextureName = Sprites[i].GetTextureFilename();
		}
	}
	DrawSpriteList( Sprites, CurrentLenght, CurrentSprite);
}

void L_SpriteRenderer::DrawSpriteList(L_Sprite* Sprites, unsigned int NumSprites, unsigned int Offset)
{
	static ID3D11ShaderResourceView* tempTexture;
	tempTexture = ResourceManager->GetTexture(Sprites[Offset].GetTextureFilename());
	DeviceContext->PSSetShaderResources( 0, 1, &tempTexture );

	static float uvWidth;
	static SpriteVertex* temp = new SpriteVertex[6*1000];
	static ID3D11Buffer* tVB;
	unsigned int Stride = sizeof(SpriteVertex);
	unsigned int BufferOffset = 0;

	static int CurSpr;	// CurrentSprite

	for(unsigned int i=0; i<NumSprites; i++)
	{
		CurSpr = i+Offset;
		uvWidth = Sprites[CurSpr].GetUV2().x - Sprites[i].GetUV1().x;

		temp[6*i+0].pos = float3((float)Sprites[CurSpr].GetPosX()-400.0f, (float)-Sprites[CurSpr].GetPosY()+300.0f, 0.0f);
		temp[6*i+0].texCoord = Sprites[CurSpr].GetUV1();

		temp[6*i+1].pos = float3((float)(Sprites[CurSpr].GetPosX()+Sprites[CurSpr].GetWidth())-400.0f, (float)-Sprites[CurSpr].GetPosY()+300.0f, 0.0f);
		temp[6*i+1].texCoord = Sprites[CurSpr].GetUV1();
		temp[6*i+1].texCoord.x += uvWidth;

		temp[6*i+2].pos = float3((float)(Sprites[CurSpr].GetPosX()+Sprites[CurSpr].GetWidth())-400.0f, (float)(-Sprites[CurSpr].GetPosY()-Sprites[CurSpr].GetHeight())+300.0f, 0.0f);
		temp[6*i+2].texCoord = Sprites[CurSpr].GetUV2();

		temp[6*i+3].pos = float3((float)Sprites[CurSpr].GetPosX()-400.0f, (float)-Sprites[i].GetPosY()+300.0f, 0.0f);
		temp[6*i+3].texCoord = Sprites[CurSpr].GetUV1();

		temp[6*i+4].pos = float3((float)(Sprites[CurSpr].GetPosX()+Sprites[CurSpr].GetWidth())-400.0f, (float)(-Sprites[CurSpr].GetPosY()-Sprites[CurSpr].GetHeight())+300.0f, 0.0f);
		temp[6*i+4].texCoord = Sprites[CurSpr].GetUV2();

		temp[6*i+5].pos = float3((float)Sprites[CurSpr].GetPosX()-400.0f, (float)(-Sprites[CurSpr].GetPosY()-Sprites[CurSpr].GetHeight())+300.0f, 0.0f);
		temp[6*i+5].texCoord = Sprites[CurSpr].GetUV2();
		temp[6*i+5].texCoord.x -= uvWidth;
	}

	VertexBuffer->Update(DeviceContext, temp, 6*NumSprites*sizeof(SpriteVertex),0);

	tVB = VertexBuffer->GetBuffer();
	DeviceContext->IASetVertexBuffers( 0, 1, &tVB, &Stride, &BufferOffset );
	DeviceContext->Draw( 6*NumSprites, 0 );	
}